/*
 Copyright (c) 2013 MeherTJ G. All rights reserved.
 License: LGPL for personnal study or free software.
 */

#pragma once

/**
 add external/<...>/include/freetype2 to the include path
 */
#include "ft2build.h"
#include "freetype.h"

#include <vector>
#include <map>
#include <memory>

#include "zen_exception.h"

namespace Zen {
	
	struct FTFontChar
	{
		uint32_t unicode = 0;
		std::vector<uint8_t> bitmap;

		int width = 0;
		int height = 0;
		
		int bitmap_left = 0;
		int bitmap_top = 0;
		
		int view_width = 0;
		int view_height = 0;
	};

	struct FTFontConfig
	{
		int   width  = 16;
		int   height = 16;
		float italic = 0; // [0., 1.]
		float bold_x = 0; // px
		float bold_y = 0; // px
	};
	
	class FTFont
	{
	protected:
		FTFont() = default;
		virtual ~FTFont() = default;
	public:
		struct Info {
			int width = 0;
			int height = 0;
			int text_height = 0;
			int ascender = 0;
			int max_advance = 0;
		};

		virtual std::shared_ptr<FTFontChar>
		createCharBitmap(uint32_t unicode, FTFontConfig const & config) = 0;

		virtual Info getInfo(FTFontConfig const & config) = 0;
	};
	
	class FTFontLibrary
	{
	public:
		static FTFontLibrary * Get();
		
		virtual std::shared_ptr<FTFont> createFTFont(std::vector<uint8_t> const & data) = 0;
		
	protected:
		FTFontLibrary() = default;
		virtual ~FTFontLibrary() = default;
	};

	class FTFontBrush
	{
	public:
		static std::shared_ptr<FTFontBrush> Create(std::shared_ptr<FTFont> font, FTFontConfig config);

		std::shared_ptr<FTFontChar> getCharBitmap(uint32_t unicode);

		std::shared_ptr<FTFont> getFTFont() const;

		FTFontConfig const & getConfig() const;

		FTFont::Info const & getInfo() const;

	public:
		virtual ~FTFontBrush() = default;

	protected:
		FTFontBrush() = default;
	protected:
		FTFontConfig m_config;
		std::shared_ptr<FTFont> m_font;
		std::map<uint32_t, std::shared_ptr<FTFontChar> > m_chars;
		FTFont::Info m_font_info;
//		int m_line_base = 0;
//		int m_text_height = 0;
	};

	class FTFonts
	{
	public:
		static FTFonts * Get();

		std::shared_ptr<FTFont> setFTFont(std::string const & name, std::vector<uint8_t> const & data);

		std::shared_ptr<FTFont> getFTFont(std::string const & name);
	protected:
		FTFonts() = default;
		virtual ~FTFonts() = default;
		
	protected:
		std::map<std::string, std::shared_ptr<FTFont> > m_fonts;
	};
}
